package com.xb.loan.cashier.biz.task.plat;

import com.xb.loan.cashier.biz.constant.FundConst;
import com.xb.loan.cashier.biz.dao.bean.CashierChargeOrder;
import com.xb.loan.cashier.biz.service.CashierAccountService;
import com.xb.loan.cashier.biz.service.CashierChargeOrderService;
import com.xb.loan.cashier.biz.task.BaseTask;
import com.xb.loan.cashier.biz.util.Configure;
import com.xb.loan.cashier.biz.util.FileUtil;
import com.xb.loan.cashier.service.constant.ICashierEnumConst;
import com.xb.loan.fund.service.IFundService;
import com.xb.loan.util.DateHelper;
import com.xb.loan.util.file.FileHelper;
import com.xb.loan.util.ftp.FtpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 与平台充值对账任务
 */
@Component(value="platAccountChargeTask")
@Scope(value="prototype")
public class PlatAccountChargeTask extends BaseTask {
    
    private static final Logger log = LoggerFactory.getLogger(PlatAccountChargeTask.class);
    
    private static final String NAME_SPLIT = "_";
    
    private static final String SUFFIX = ".txt";//充值对账文件后辍
    
    private static final String FTP_ACCOUNT_DIR = "platAccountCharge";//FTP目录
    
    private static final String ACCOUNT_DIR_SUCC = "succ";//处理成功目录
    
    private static final String ACCOUNT_DIR_FAIL = "fail";//处理失败目录
    
    private static final long MILLIS = 60*1000* Configure.getIntValue("job.plataccountcharge.sleep");
    
    private String accountPeriod;

    public void setAccountPeriod(String accountPeriod) {
        this.accountPeriod = accountPeriod;
    }

    /**
     *充值对账
     *1.查询当前账期是否已经与第三方对账(status>0)
     * 2.如果已对账完成，查询当前账期内是否有处理成功且未对账的数据(status=2 and account_status=0)
     * 3.如果账期内不存在未对账记录，查询当前账期内处理成功并且对账完成的数据(status=2 and account_status=1)
     * 4.按页查询数据写入账期_时间戳.txt文件并上传FTP服务器
     * 5.通知业务系统处理对账 
     * 6.如果文件上传失败或通知业务系统出错将本地文件移入fail中，否则移入succ。
     *
     */
    @Override
    public void execute() {
        CashierAccountService cashierAccountService = (CashierAccountService)ctx.getBean("cashierAccountService");
        CashierChargeOrderService cashierChargeOrderService = (CashierChargeOrderService)ctx.getBean("cashierChargeOrderService");
        int start = 0;
        int limit = Configure.getIntValue("job.plataccountcharge.pagesize");
        int pageNum = 0;
        File file = null;
        String filePath = null;
        String fileName = null;
        String destPath = null;
        while (true) {
            int count = cashierAccountService.queryCountByAccountPeriod(accountPeriod, ICashierEnumConst.CashierOrderType.charge.getCode());
            if (count==1) {
                count = cashierChargeOrderService.queryCountByAccountDayPlat(accountPeriod);//与平台只对成功的数据
                if (count==0) {
                    count = cashierChargeOrderService.queryAccountCount(accountPeriod);
                    log.info("execute 当前账期："+accountPeriod+"与第三方对账成功总条数："+count);
                    if (count>0) {
                        StringBuffer rowData = null;//每行数据
                        List<String> pageData = null;//每页数据
                        String spilt = ICashierEnumConst.AccountStrSpilt.COMMON.getCode();
                        filePath = Configure.getStringValue("job.plataccountcharge.savePath");
                        String timeStamp = DateHelper.DateToString("yyyyMMddHHmmss", new Date());
                        fileName = accountPeriod.concat(NAME_SPLIT).concat(timeStamp).concat(SUFFIX);
                        file = new File(filePath+ File.separator+fileName);
                        if (!file.getParentFile().exists()) {
                            file.getParentFile().mkdirs();
                        }
                        log.info("execute localFilePath="+file.getAbsolutePath());
                        while (true) {
                            List<CashierChargeOrder> list = cashierChargeOrderService.queryAccountByPage(accountPeriod, start, limit);
                            if (list==null || list.size()==0) {
                                log.info("execute 当前账期："+accountPeriod+"未获取到数据列表,已退出!");
                                break;//结束分页查询
                            }
                            pageData = new ArrayList<String>();
                            if (pageNum==0) {//第一页中首行记录总条数
                                pageData.add(count+"");
                            }
                            for (CashierChargeOrder cco : list) {
                                rowData = new StringBuffer();
                                rowData.append(cco.getCashierOrderId()).append(spilt);
                                rowData.append(cco.getOrderId()).append(spilt);
                                rowData.append(cco.getPlatId()).append(spilt);
                                rowData.append(cco.getPartnerId()).append(spilt);
                                rowData.append(cco.getUserId()).append(spilt);
                                rowData.append(cco.getMoney()).append(spilt);
                                rowData.append(cco.getAccountDayPlat()).append(spilt);
                                rowData.append(cco.getPayChannelType());
                                pageData.add(rowData.toString());
                            }
                            //按页写数据
                            FileHelper.writeFileAppand(file, pageData);
                            //计算start
                            start = (++pageNum)*limit;
                        }
                        destPath = filePath+ File.separator+ACCOUNT_DIR_FAIL;
                        //将生成的txt文件上传到FTP
                        FtpUtil ftpUtil = (FtpUtil)ctx.getBean("ftpUtil");
                        boolean flag = ftpUtil.upload(file.getAbsolutePath(), FTP_ACCOUNT_DIR, fileName);
                        if (flag) {
                            //通知业务平台系统
                            String address = FTP_ACCOUNT_DIR.concat(File.separator).concat(fileName);
                            try {
                            	IFundService fundService = (IFundService)ctx.getBean("fundService");
                                fundService.checkAccount(address, accountPeriod, FundConst.FundType_Charge);
                                destPath = filePath+ File.separator+ACCOUNT_DIR_SUCC;
                                log.info("execute 当前账期："+accountPeriod+"已通知业务系统对账");
                            } catch (Exception e) {
                                log.error("execute 当前账期："+accountPeriod+"通知业务系统对账异常",e);
                            }
                        }
                        try {
                            FileUtil.moveFileToDir(file, destPath);
                            log.info("execute 已将充值对账文件"+fileName+"移至："+destPath);
                        } catch (IOException e) {
                            log.error(e.getMessage(),e);
                        }
                        log.info("execute 当前账期："+accountPeriod+"数据处理完成");
                        break;//结束任务
                    }
                }else {
                    log.info("execute 当前账期："+accountPeriod+"内剩余"+count+"条记录未与第三方对账");
                }
            }else {
                log.info("execute 当前账期："+accountPeriod+"还未与第三方对账");
            }
            try {
                log.debug("execute 休眠"+MILLIS+"毫秒");
                Thread.sleep(MILLIS);
            } catch (InterruptedException e) {
                log.error(e.getMessage(),e);
            }
        }
    }
}
